package cc.yaomm.common.basic.util;

import com.google.common.base.Splitter;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>@Description : 字符串处理工具类</p>
 * <p>@Author : QiLin.Xing </p>
 * <p>@Date : 2018/8/2 13:58 </p>
 */
public final class StringsUtils {

    /**
     * <p>@Description : 字符串数组排序[根据ASCII码排序，从小到大]</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/8/2 13:59 </p>
     *
     * @param strings 字符串数组
     */
    public static void sort(String[] strings) {
        if (strings.length == 0) {
            return;
        }
        for (int i = 0; i < strings.length - 1; i++) {
            for (int j = 0; j < strings.length - 1 - i; j++) {
                int total1 = 0;
                for (byte b : strings[j].getBytes()) {
                    total1 += b;
                }
                int total2 = 0;
                for (byte b : strings[j + 1].getBytes()) {
                    total2 += b;
                }

                if (total1 > total2) {
                    String temp = strings[j];
                    strings[j] = strings[j + 1];
                    strings[j + 1] = temp;
                }
            }
        }
    }

    /**
     * <p>@Description : 省略字符串</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/12/11 15:07 </p>
     *
     * @param value     字符串
     * @param prefixLen 前显示多少位
     * @param suffixLen 后显示多少位
     * @return
     */
    public static String omitString(String value, int prefixLen, int suffixLen) {
        if (StringUtils.isEmpty(value)) {
            return "";
        } else {
            prefixLen = Math.min(prefixLen, value.length());
            suffixLen = Math.min(suffixLen, value.length());
            return value.substring(0, prefixLen) + "*****" + value.substring(value.length() - suffixLen, value.length());
        }
    }

    /**
     * <p>@Description : 将数组格式成[][][]字符串</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/8/21 10:32 </p>
     *
     * @param integers 字符串数组
     * @return [][][][][][]
     */
    public static String formatStrings(Integer[] integers) {
        if (integers.length == 0) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (int str : integers) {
            sb.append("[" + str + "]");
        }
        return sb.toString();
    }

    /**
     * <p>@Description : 将格式为[][][]的字符串分隔成数组</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/3/15 14:08 </p>
     * String a = "[1][2][3]" --> Integer[] b = new Integer[]{1,2,3}
     */
    public static Integer[] splitStrings(String str) {
        if (StringUtils.isNotBlank(str)) {
            String temp = str.replaceAll(" ", "").replace("[", "");
            String[] taregets = temp.split("]");
            if (ArrayUtils.isNotEmpty(taregets)) {
                Integer[] addr = new Integer[taregets.length];
                int i = 0;
                for (String apid : taregets) {
                    if (StringUtils.isNotBlank(apid)) {
                        addr[i] = Integer.valueOf(apid.trim());
                        i++;
                    }
                }
                return addr;
            }
        }
        return new Integer[]{};
    }

    /**
     * <p>@description : 将格式为1,2,3,的字符串分隔成List </p>
     * <p>@author : Jia.Li </p>
     * <p>@date : 2020/6/22 14:14 </p>
     *
     * @param str 字符串
     * @return String a = "1,2,3," --> List<Integer> a = Lists.newArrayList(1,2,3);
     **/
    public static List<Integer> splitToListInt(String str) {
        List<String> strList = Splitter.on(",").trimResults().omitEmptyStrings().splitToList(str);
        return strList.stream().map(Integer::parseInt).collect(Collectors.toList());
    }

    /**
     * <p>@Description : 随机生成字符串</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/8/22 15:19 </p>
     *
     * @param length    字符串长度
     * @param character 是否包含字母
     * @param isUpper   是否转大写
     * @return
     */
    public static String randomCode(int length, boolean character, Boolean isUpper) {
        String[] numbers = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        String[] uppers = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
        String[] lowers = new String[]{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        List<String> list = new ArrayList<>();
        list.addAll(Arrays.asList(numbers));
        if (character) {
            list.addAll(Arrays.asList(uppers));
            list.addAll(Arrays.asList(lowers));
        }
        for (int i = 0; i < length; i++) {
            sb.append(list.get(random.nextInt(list.size())));
        }
        if (isUpper == null) {
            return sb.toString();
        } else {
            return isUpper ? sb.toString().toUpperCase() : sb.toString();
        }
    }

    /**
     * <p>@Description : 转换字母大小写</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2018/10/26 14:52 </p>
     *
     * @param str     字符串
     * @param isUpper true-大写 false-小写
     * @return
     */
    public static String toFirstLetter(String str, boolean isUpper) {
        //return (isUpper ? str.substring(0, 1).toUpperCase() : str.substring(0, 1).toLowerCase()) + str.substring(1);
        return isUpper ? StringUtils.capitalize(str) : StringUtils.uncapitalize(str);
    }

    /**
     * <p>@Description : 堆栈信息转换成字符串</p>
     * <p>@Author : QiLin.Xing </p>
     * <p>@Date : 2019/5/14 0014 下午 18:36 </p>
     */
    public static String printStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        throwable.printStackTrace(new PrintWriter(sw, true));
        return sw.getBuffer().toString();
    }

    /**
     * <p>@Description : 逗号格式的字符串去掉指定值</p>
     * <p>@Author : ShiLin.Liu </p>
     * <p>@Date : 2019/12/24 11:03 </p>
     *
     * @param removeStr: 移除的值
     * @param oldStr:    原始字符串
     * @return java.lang.String
     **/
    public static String removeOneFromComma(String removeStr, String oldStr) {
        String[] tmp = oldStr.split(",");
        StringBuilder buffer = new StringBuilder();
        for (String s : tmp) {
            if (!s.equals(removeStr)) {
                buffer.append(s).append(",");
            }
        }
        return StringUtils.isBlank(buffer.toString()) ? "" : buffer.toString().substring(0, buffer.length() - 1);
    }

    /**
     * <p>@Description : 验证是否为整数</p>
     * <p>@Author : ShiLin.Liu </p>
     * <p>@Date : 2020/2/14 16:15 </p>
     *
     * @param str: 传入字符串
     * @return boolean
     **/
    public static boolean isNumeric(String str) {
        for (int i = str.length(); --i >= 0; ) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>@description : 只显示最后几位 </p>
     * <p>@author : Jia.Li </p>
     * <p>@date : 2020/1/6 15:26 </p>
     *
     * @param value     字符串
     * @param suffixLen 显示多少位
     * @return 结果
     */
    public static String getLastString(String value, int suffixLen) {
        if (null == value) {
            return "";
        }
        suffixLen = Math.min(suffixLen, value.length());
        return value.substring(value.length() - suffixLen);
    }

    /**
     * <p>@Description : 生成随机数</p>
     * <p>@Author : ShiLin.Liu </p>
     * <p>@Date : 2020/4/24 14:40 </p>
     *
     * @param digit: 位数
     * @return java.lang.String
     **/
    public static String getRandomNumber(int digit) {
        //生成随机数
        Random rand = new Random();
        StringBuilder cardNumber = new StringBuilder();
        for (int a = 0; a < digit; a++) {
            cardNumber.append(rand.nextInt(10));
        }
        return cardNumber.toString();
    }
}
